<script setup lang="ts">
import { ref, toRef, reactive, readonly, watch } from "vue";

const props = defineProps<{ fileds: string[], data: { price: number, goodsCode:string, [key: string]: string | number }[] }>()

const fileds = props.fileds as string[];
const data = toRef(props, 'data')

const compare = (params: { [key: string]: string }, obj: { [key: string]: string | number }) => {
    let result = true
    for (let key in params) {
        if (params[key] !== obj[key]) {
            result = false
        }
    }
    return result
}

const getOption = (filed: string, params: { [key: string]: string } = {}): { key: string, value: string }[] => {
    let list;
    if (filed === fileds[0]) {
        list = data.value || []
    } else {
        list = data.value?.filter(item => compare(params, item as any)) || []
    }
    list = list.map((item: any) => item[filed])
    list = Array.from(new Set(list))
    list = list.map(item => ({ key: filed, value: item }))
    console.log('filed:', filed, list, data.value)
    return list
}

const getPrice = (params: { [key: string]: string }) => {
    const price = data.value.find(item => compare(params, item))?.price || 'null'
    return price
}

const getGoodsCode = (params: { [key: string]: string }) => {
    const goodsCode = data.value.find(item => compare(params, item))?.goodsCode || ''
    return goodsCode
}

const emit = defineEmits(['update:spec', 'update:price', 'update:goodsCode'])

const select = reactive<{ [key: string]: { key: string, value: string } }>({})
const option = reactive<{ [key: string]: { key: string, value: string }[] }>({})
const price = ref<number | string>('')
const goodsCode = ref<string>('')

for (let filed of fileds) {
    select[filed] = { key: filed, value: '' }
    if (filed === fileds[0]) {
        option[filed] = getOption(filed)
    } else {
        option[filed] = []
    }
}

const handleChange = (val: { key: string, value: string }) => {
    const filedIndex = fileds.findIndex(item => item === val.key)
    const params: { [key: string]: string } = {}
    fileds.forEach((filed: string, index: number) => {
        if (index <= filedIndex) {
            params[filed] = select[filed].value
        }
        if (index === filedIndex + 1) {
            select[filed] = { key: filed, value: '' }
            option[filed] = getOption(filed, params)
        }
        if (index > filedIndex + 1) {
            select[filed] = { key: filed, value: '' }
            option[filed] = []
        }
    })
    if (filedIndex === fileds.length - 1) {
        price.value = getPrice(params)
        goodsCode.value = getGoodsCode(params)
    } else {
        price.value = ''
        goodsCode.value = ''
    }
    emit('update:price', price.value)
    emit('update:goodsCode', goodsCode.value)
    emit('update:spec', readonly(select))
}

watch(data, () => {
    const params: { [key: string]: string } = {}
    let isPrice = true
    for (let filed of fileds) {
        option[filed] = getOption(filed, params);
        if (select[filed].value) {
            params[filed] = select[filed].value
        } else {
            isPrice = false
            break
        }
    }
    if (isPrice) {
        price.value = getPrice(params)
        emit('update:price', price.value)
        goodsCode.value = getGoodsCode(params)
        emit('update:goodsCode', goodsCode.value)
    }
})

</script>

<template>
    <div class="spec-price">
        <div class="cell" v-for="filed in fileds" :key="filed">
            <el-select v-model="select[filed]" value-key="value" @change="handleChange">
                <el-option
                    v-for="item in option[filed]"
                    :label="item.value"
                    :value="item"
                    :key="item.value"
                ></el-option>
            </el-select>
        </div>
    </div>
</template>

<style lang="scss" scoped>
.spec-price {
    display: flex;
    .cell {
        flex: 1;
        padding: 4px;
    }
    .el-select {
        width: 100%;
    }
}
</style>
